﻿#include "bar_generator.h"   // 包含 bar 生成器的头文件
#include "time_utils.hpp"    // 包含时间工具的头文件

using namespace lt;          // 使用 lt 命名空间

// 插入 tick 数据，用于生成 bar 数据
// 参数：
// - tick: 当前的 tick 数据
void bar_generator::insert_tick(const tick_info& tick)
{
    // 判断当前 tick 的分钟是否与上一个生成的分钟间隔超过设定的周期
    if (tick.time / ONE_MINUTE_MILLISECONDS - _minute >= _period)
    {
        // 合成 bar 数据并通知接收器
        if (_minute > 0)
        {
            // 遍历所有的 bar 接收器，并调用它们的 on_bar 函数
            for (auto it : _bar_callback)
            {
                it->on_bar(_bar);
            }
        }
        // 更新当前的分钟时间戳
        _minute = (tick.time / ONE_MINUTE_MILLISECONDS);
        // 清除当前 bar 数据，准备生成新的 bar
        _bar.clear();
    }

    // 计算当前 tick 的成交量变化
    uint32_t delta_volume = static_cast<uint32_t>(tick.volume - _prev_volume);
    
    // 如果 bar 的开盘价为 0，说明是新生成的 bar，初始化 bar 数据
    if (_bar.open == .0F)
    {
        // 初始化各种 bar 数据
        _poc_data.clear();                       // 清空 POC 数据
        _bar.id = tick.id;                       // 设置 bar 的合约 ID
        _bar.period = _period;                   // 设置 bar 的周期
        _bar.open = tick.price;                  // 设置开盘价为当前价格
        _bar.close = tick.price;                 // 设置收盘价为当前价格
        _bar.high = tick.price;                  // 设置最高价为当前价格
        _bar.low = tick.price;                   // 设置最低价为当前价格
        _bar.time = _minute * ONE_MINUTE_MILLISECONDS;  // 设置 bar 的时间
        _bar.volume = delta_volume;              // 设置 bar 的成交量
        _bar.price_step = _price_step;           // 设置价格步长
        _poc_data[tick.price] = delta_volume;    // 初始化 POC 数据
        _bar.poc = tick.price;                   // 设置 POC 价格为当前价格
    }
    else 
    {
        // 更新 bar 数据：最高价、最低价、收盘价、成交量等
        _bar.high = std::max(_bar.high, tick.price);  // 更新最高价
        _bar.low = std::min(_bar.low, tick.price);    // 更新最低价
        _bar.close = tick.price;                      // 更新收盘价
        _bar.volume += delta_volume;                  // 累计成交量
        _poc_data[tick.price] += delta_volume;        // 更新 POC 数据
    }

    // 更新 POC，如果当前价格的成交量大于现有的 POC，则更新 POC
    if (_poc_data[tick.price] > _poc_data[_bar.poc])
    {
        _bar.poc = tick.price;
    }

    // 判断是否是主动卖出
    if (tick.price == tick.buy_price())
    {
        // 主动卖出，更新卖出成交量和 bar 的 delta 值
        _bar.price_sell_volume[tick.price] += delta_volume;
        _bar.delta -= delta_volume;
    }

    // 判断是否是主动买入
    if (tick.price == tick.sell_price())
    {
        // 主动买入，更新买入成交量和 bar 的 delta 值
        _bar.price_buy_volume[tick.price] += delta_volume;
        _bar.delta += delta_volume;
    }

    // 更新前一个 tick 的成交量
    _prev_volume = tick.volume;
}

// 添加 bar 数据的接收器
// 参数：
// - receiver: 接收 bar 数据的接收器对象
void bar_generator::add_receiver(bar_receiver* receiver)
{
    // 检查接收器是否已经存在，如果不存在则添加到接收器集合中
    auto it = _bar_callback.find(receiver);
    if (it == _bar_callback.end())
    {
        _bar_callback.insert(receiver);
    }
}

// 移除 bar 数据的接收器
// 参数：
// - receiver: 要移除的接收器对象
void bar_generator::remove_receiver(bar_receiver* receiver)
{
    // 检查接收器是否存在，如果存在则从集合中移除
    auto it = _bar_callback.find(receiver);
    if (it != _bar_callback.end())
    {
        _bar_callback.erase(receiver);
    }
}

// 判断 bar 生成器是否有效（是否有接收器）
// 返回值：如果接收器集合为空，则返回 true，否则返回 false
bool bar_generator::invalid() const
{
    return _bar_callback.empty();
}
    